import datetime

from aiogram import Router, types, F, exceptions
from aiogram.fsm.context import FSMContext
from aiogram.utils.markdown import hpre, hlink, hbold, hitalic

import config
from handlers.users_message import delete_mess
from keyboards.callbacks_data import MenuCategory
from loader import logger, db, bot, scheduler
from filters.admin_filter import IsAdmin
from keyboards import menu_keys
from utils import DefStopWordsStates

router = Router()
router.message.bind_filter(IsAdmin)
router.callback_query.bind_filter(IsAdmin)
router.message.filter(F.chat.type == "private")


# router.callback_query.filter(F.chat.type == "private")


@router.message(commands='start')
async def start(message: types.Message):
    await message.answer('Вот чем вы можете управлять:', reply_markup=menu_keys.admin_menu())


@router.message(commands='stop_default')
async def start(message: types.Message, context: dict):
    stop_words = context['stop_words']
    messages = []
    temp_text = ''
    for i in stop_words:
        temp_text += f"{i}\n"
        if len(temp_text) > 4000:
            messages.append(temp_text)
            temp_text = ''
        if i is stop_words[-1]:
            messages.append(temp_text)

    for list_words in messages:
        no_words = 'Сюда пока что ничего не добавили((\nНапишите <code>/stop_add </code>' \
                   '[слово] - чтобы добавить слово в фильтр\n'
        text = f'Список стоп слов назначаемых по-умолчанию: \n{hpre(list_words)}' if len(stop_words) > 0 else no_words
        if len(messages) > 1 and list_words not in messages[0]:
            text = hpre(list_words)
        mess = await message.answer(text)
        scheduler.add_job(delete_mess, args=(mess,), trigger='date',
                          run_date=datetime.datetime.now() + datetime.timedelta(minutes=2))
        await message.delete()


@router.callback_query(MenuCategory.filter(F.category == 'statistic'))
async def statistics(call: types.CallbackQuery, callback_data: MenuCategory, context: dict):
    """
    get count all users
    """
    users = len(context['users'])
    chats = len(db.select_channels_for_ads())
    text = f'' \
           f'{hbold("Ботом пользуется")}: {hitalic(users)} человек\n' \
           f'{hbold("Ваша реклама покажется в")}: {hitalic(chats)} чатах\n'
    await call.message.edit_text(text)
    await call.message.edit_reply_markup(menu_keys.back(1, 'stop_words'))


@router.callback_query(
    MenuCategory.filter(F.category == 'default_words'),
    MenuCategory.filter(F.action.in_({'add', 'delete'})),
)
async def add_del_words(call: types.CallbackQuery, callback_data: MenuCategory, context: dict, state: FSMContext):
    words_list = '\n'.join(context['stop_words'])
    too_long = 'Все слова сюда не поместились. Нажми /stop_default, чтобы увидеть полный список.\n\n'
    if callback_data.action == 'add':
        await state.set_state(DefStopWordsStates.add)
        await call.message.edit_text(
            f"Слова по умолчанию:\n{hpre(words_list[:4000])}\n\n"
            f"{too_long if len(words_list) > 4000 else ''}"
            f"Напиши мне что хочешь добавить. Можно добавить или удалить сразу нескольслко стоп слов."
            "Для этого разделяй их по строкам")
        await call.message.edit_reply_markup(menu_keys.back(2, 'default_words'))
    elif callback_data.action == 'delete':
        await state.set_state(DefStopWordsStates.delete)
        await call.message.edit_text(
            f"Слова по умолчанию:\n{hpre(words_list[:4000])}\n\n"
            f"{too_long if len(words_list) > 4000 else ''}"
            f"Напиши мне что хочешь удалить. Можно добавить или удалить сразу нескольслко стоп слов."
            "Для этого разделяй их по строкам")
        await call.message.edit_reply_markup(menu_keys.back(2, 'default_words'))
    await state.update_data(call=call)
    scheduler.add_job(state.clear, trigger='date',
                      run_date=datetime.datetime.now() + datetime.timedelta(minutes=3))


@router.message(DefStopWordsStates.add)
async def stop_words_add(m: types.Message, context: FSMContext, state: FSMContext):
    data = await state.get_data()
    call = data['call']
    words = m.text.split('\n')
    for word in words:
        db.add_word(0, word)
    context['stop_words'] = db.select_default_word()
    mess = await m.answer(f"Добавил: \n{hbold(m.text)}")
    await m.delete()
    await add_del_words(call, MenuCategory(level=2, category='default_words', action='add'), context, state)
    scheduler.add_job(delete_mess, args=(mess,), trigger='date',
                      run_date=datetime.datetime.now() + datetime.timedelta(seconds=10))


@router.message(DefStopWordsStates.delete)
async def stop_words_del(m: types.Message, context: FSMContext, state: FSMContext):
    data = await state.get_data()
    call = data['call']
    words = m.text.split('\n')
    for word in words:
        db.delete_word(0, word)
    context['stop_words'] = db.select_default_word()
    mess = await m.answer(f"Удалил: \n{hbold(m.text)}")
    await m.delete()
    await add_del_words(call, MenuCategory(level=2, category='default_words', action='delete'), context, state)
    scheduler.add_job(delete_mess, args=(mess,), trigger='date',
                      run_date=datetime.datetime.now() + datetime.timedelta(seconds=10))


@router.callback_query(
    MenuCategory.filter(F.category == 'default_words'),
)
async def show_default_words(call: types.CallbackQuery, callback_data: MenuCategory, context: dict, state: FSMContext):
    current_level = callback_data.level
    if callback_data.action == 'back':
        if current_level == 2:
            await state.clear()
        current_level -= 1
    stop_words = '\n'.join(context['stop_words'])
    levels = {
        0: menu_keys.admin_menu() if call.from_user.id in config.ADMIN_ID else menu_keys.client_menu(),
        1: menu_keys.action(2, 'default_words'),
        2: menu_keys.back(2, 'default_words'),
    }
    texts = {
        0: "Вот чем вы можете управлять:",
        1: f"Слова по умолчанию:\n<code>{stop_words}</code>\nДоступны такие действия: \n",
        2: "Напиши слова/фразы, которые хочешь добавить. Можно добавить или удалить сразу нескольслко стоп слов."
           "Для этого разделяй их по строкам"
    }
    await call.message.edit_text(texts[current_level])
    await call.message.edit_reply_markup(levels[current_level])


@router.callback_query(
    MenuCategory.filter(),
    MenuCategory.filter(F.level <= 5),
)
async def show_menu(call: types.CallbackQuery, callback_data: MenuCategory, state: FSMContext):
    logger.debug(callback_data)
    current_level = callback_data.level
    if callback_data.action == 'back':
        current_level -= 1

    levels = {
        0: menu_keys.admin_menu(),
    }
    texts = {
        0: "Вот чем вы можете управлять:",
    }
    await call.message.edit_text(texts[current_level], disable_web_page_preview=True)
    await call.message.edit_reply_markup(levels[current_level])
